/*******************************************************************************
 * Copyright 2010 MoBrite (A venture of Kinara Systems Private Limited)
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/
package com.mobrite.domaindroid.db;

import java.util.Date;

import com.mobrite.domaindroid.util.Logger;
import com.mobrite.domaindroid.util.Util;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

public class DomainDroidDbAdapter {

    public static final String KEY_DOMAIN = "domain";
    public static final String KEY_TLD = "tld";
    public static final String KEY_ROWID = "_id";
    public static final String KEY_ISAVAILABLE = "isavailable";
    public static final String KEY_FAVORITE = "favorite";
    public static final String KEY_TIMESTAMP = "last_checked_timestamp";

    public static final String[] columnList	= new String[] { KEY_ROWID, KEY_DOMAIN,
		KEY_TLD, KEY_ISAVAILABLE, KEY_TIMESTAMP, KEY_FAVORITE };
    
    public static String orderBy = KEY_DOMAIN;
    
    private static final String TAG = "DomainDroidDbAdapter";
    private DatabaseHelper mDbHelper;
    private SQLiteDatabase mDb;
    
    /**
     * Database creation sql statement
     */
    private static final String DATABASE_CREATE =
            "create table domains (_id integer primary key autoincrement, "
                    + "domain text not null, tld text not null, last_checked_timestamp date, isavailable integer, favorite integer);";

    private static final String DATABASE_NAME = "domaindata";
    private static final String DATABASE_TABLE = "domains";
    private static final int DATABASE_VERSION = 2;

    private final Context mCtx;

    private static class DatabaseHelper extends SQLiteOpenHelper {

        DatabaseHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {

            db.execSQL(DATABASE_CREATE);
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
                    + newVersion + ", which will destroy all old data");
            db.execSQL("DROP TABLE IF EXISTS domains");
            onCreate(db);
        }
    }
    
    public DomainDroidDbAdapter(Context context) {
    	this.mCtx = context;
    }

    public DomainDroidDbAdapter open() throws SQLException {
        mDbHelper = new DatabaseHelper(mCtx);
        mDb = mDbHelper.getWritableDatabase();
        return this;
    }
    
    public void close() {
        mDbHelper.close();
    }

    public long addDomain (String domain, String tld, boolean available, long timestamp) {
    	
    	Cursor cursor = getDomain(domain, tld);
    	
    	if (cursor==null || cursor.getCount()==0) {
    		// Domain.tld not already in db, create new record
	        ContentValues initialValues = new ContentValues();
	        initialValues.put(KEY_DOMAIN, domain);
	        initialValues.put(KEY_TLD, tld);
	        initialValues.put(KEY_ISAVAILABLE, available?1:0);
	        initialValues.put(KEY_FAVORITE, 0);               
	        initialValues.put(KEY_TIMESTAMP, Util.getFormattedDateForDb(timestamp));
	        if (cursor!=null) {
	        	cursor.close();
	        }
	        return mDb.insert(DATABASE_TABLE, null, initialValues);
    	}
    	else {
    		// Domain.tld already present in db, update existing record
    		Logger.d(domain+"."+tld+" already exists, updating...");
    		long rowId = cursor.getLong(cursor.getColumnIndex(KEY_ROWID));
    		DomainObject domainObj = getDomainObject(rowId);
    		domainObj.setAvailable(available ? 1 : 0);
    		domainObj.setLastCheckedTimestamp(timestamp);
    		cursor.close();
    		return updateDomain(rowId, domainObj) ? rowId : -1;
    	}
    }
    
    public boolean deleteDomain (long rowId) {
    	return mDb.delete(DATABASE_TABLE, KEY_ROWID+"="+rowId, null)>0;
    }
    
    public Cursor getDomain(long rowId) {
    	
		Cursor mCursor = mDb.query(true, DATABASE_TABLE, columnList,
				KEY_ROWID + "=" + rowId, null, null, null, null, null);
		if (mCursor != null) {			
			mCursor.moveToFirst();
		}		
		return mCursor;
    }
    
    public DomainObject getDomainObject (long rowId) {
    
    	Cursor cursor = getDomain(rowId);
		DomainObject dobj = new DomainObject(cursor.getString(cursor
				.getColumnIndex(KEY_DOMAIN)), cursor.getString(cursor
				.getColumnIndex(KEY_TLD)), cursor.getInt(cursor
				.getColumnIndex(KEY_ISAVAILABLE)), cursor.getInt(cursor
				.getColumnIndex(KEY_FAVORITE)), Util.getTimeFromDbString(cursor.getString(cursor.getColumnIndex(KEY_TIMESTAMP))));
		dobj.setRowId(rowId);
		cursor.close();
		return dobj;
    }
    
    public Cursor getDomain (String domain, String tld) {

    	Cursor mCursor =

			mDb.query(true, DATABASE_TABLE, columnList,
					KEY_DOMAIN + " = ? AND " + KEY_TLD+" = ?", new String[] {domain, tld}, null, null, null, null);
			if (mCursor != null) {
				mCursor.moveToFirst();
			}
			
			return mCursor;    	
    }
    
    public Cursor getAvailableDomains() {

		Logger.d("DBAdapter::getAvailableDomains() - orderBy="+orderBy);

		Cursor mCursor =

			mDb.query(true, DATABASE_TABLE, columnList,
					KEY_ISAVAILABLE + "=1", null, null, null, orderBy, null);
			if (mCursor != null) {
				mCursor.moveToFirst();
			}
			return mCursor;

    }
    
    public Cursor getTakenDomains() {

		Logger.d("DBAdapter::getTakenDomains() - orderBy="+orderBy);
		Cursor mCursor =

			mDb.query(true, DATABASE_TABLE, columnList,
					KEY_ISAVAILABLE + "=0", null, null, null, orderBy, null);
			if (mCursor != null) {
				mCursor.moveToFirst();
			}
			return mCursor;

    }

    public Cursor getFavouriteDomains() {
		Logger.d("DBAdapter::getFavouriteDomains() - orderBy="+orderBy);
		Cursor mCursor = mDb.query(true, DATABASE_TABLE, columnList,
					KEY_FAVORITE + "=1", null, null, null, orderBy, null);
			if (mCursor != null) {
				mCursor.moveToFirst();
			}
			return mCursor;
    }
    
    public boolean updateDomain (long rowId, DomainObject domainObj) {
        ContentValues values = new ContentValues();
        values.put(KEY_FAVORITE,domainObj.getFavorite());
        values.put(KEY_DOMAIN, domainObj.getDomain());
        values.put(KEY_TLD, domainObj.getTld());
        values.put(KEY_TIMESTAMP, Util.getFormattedDateForDb(domainObj.getLastCheckedTimestamp()));
        values.put(KEY_ISAVAILABLE, domainObj.getAvailable());

        return mDb.update(DATABASE_TABLE, values, KEY_ROWID+"="+rowId, null)>0;
    }
    
    public boolean setFavorite (long rowId, boolean favorite) {
        ContentValues values = new ContentValues();
        values.put(KEY_FAVORITE,favorite ? 1 : 0);

    	return mDb.update(DATABASE_TABLE, values, KEY_ROWID+"="+rowId, null)>0;
    }

    public boolean setFavorite (String domain, String tld, boolean favorite) {
        ContentValues values = new ContentValues();
        values.put(KEY_FAVORITE,favorite ? 1 : 0);
    	return mDb.update(DATABASE_TABLE, values, KEY_DOMAIN+"= ? AND "+KEY_TLD+" = ?", new String[] {domain, tld})>0; 	
    }
}
